package edu.map.aamas.gui;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;

import edu.map.aamas.gui.colormaps.ColorMap;
import edu.map.aamas.gui.colormaps.ColorMapFactory;
import edu.map.aamas.gui.colormaps.InterpolationColorMap;
import edu.map.aamas.rnn.RNN;
import edu.map.aamas.rnn.RnnListener;

public class RnnEvolutionDisplay extends JPanel implements RnnListener {

	private static final long serialVersionUID = 1L;

	private BufferedImage bi, aux;
	
	private int lastWidth = 0, lastHeight = 0;
	private static int stateWidth = 3;
	private RNN rnr = null;
	private ColorMap cmap = new InterpolationColorMap(
			new double[] {RNN.getInstance().xmin, 0, RNN.getInstance().xmax},
			new Color[] {Color.blue, Color.green, Color.red}
	);
	private boolean paintOnPanel = true;
	
	public RnnEvolutionDisplay() {
		addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				super.mousePressed(e);
				paintOnPanel = false;
			}
			@Override
			public void mouseReleased(MouseEvent e) {
				super.mouseReleased(e);
				paintOnPanel = true;
			}
		});
	}
	
	public void rnnUpdated(RNN rnr) {
		this.rnr = rnr;
		repaint();
	}
	
	@Override
	public void paint(Graphics g) {
		if (rnr == null)
			return;
		
		if (paintOnPanel)
			super.paint(g);
		
		// test if the size of the panel has changed since the last update
		if (bi == null || lastHeight != getHeight() || lastWidth != getWidth()) {
			bi = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
			aux = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
		}
		lastWidth = getWidth();
		lastHeight = getHeight();
		
		// translate image to the left
		aux.getGraphics().drawImage(bi, 0, 0, getWidth() - 3, getHeight(), 3, 0, getWidth(), getHeight(), null);
		bi = aux;
		
		// now draw the last (right) column based on current values 
		Graphics2D g2d = (Graphics2D) bi.getGraphics();
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		double yInc = (double)getHeight()/(double)rnr.size;
		g2d.translate(getWidth()-stateWidth, 0);
		Rectangle2D.Double rect = new Rectangle2D.Double(0,0,stateWidth,yInc);
		for (int i = 0; i < rnr.size; i++) {			
			g2d.setColor(cmap.getColor(rnr.X[i]));
			g2d.fill(rect);
			g2d.translate(0, yInc);
		}
		
		// if the mouse is pressed, the contents aren't updated
		if (paintOnPanel) {
			g.drawImage(bi, 0, 0, this);
			g.setColor(Color.white);
			g.drawString("T: "+rnr.iteration, 5, 15);
		}
	}
	
	public static void main(String[] args) throws Exception{
		JFrame test = new JFrame("test");
		RnnEvolutionDisplay disp = new RnnEvolutionDisplay();
		RNN rnr = RNN.getInstance(48);
		rnr.addRnrListener(disp);
		test.setSize(400, 100);
		test.add(disp);
		test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		test.setVisible(true);
		
		while (true) {
			rnr.update();
			Thread.sleep(30);
		}
	}
	

	public void rnnRestarted(RNN rnr) {
		bi = null;
	}

	public ColorMap getCmap() {
		return cmap;
	}

	public void setCmap(ColorMap cmap) {
		this.cmap = cmap;
	}
}
